import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.header import Header
from email.utils import formataddr

from my_package.constants import email_map
from my_package.file_utils import find_image_files


class QQMailSender:
    """
    QQ邮件发送工具类

    使用说明：
    1. 需要先在QQ邮箱设置中开启SMTP服务并获取授权码
    2. 默认使用加密传输(TLS)
    """

    def __init__(self, sender_email, auth_code, sender_name=None):
        """
        初始化邮件发送器

        :param sender_email: 发件人QQ邮箱
        :param auth_code: QQ邮箱SMTP授权码
        :param sender_name: 发件人显示名称(可选)
        """
        self.sender_email = sender_email
        self.auth_code = auth_code
        self.sender_name = sender_name if sender_name else sender_email
        self.smtp_server = 'smtp.qq.com'
        self.smtp_port = 465

    def send_email_text(self, to_email, subject, content):
        """
        发送邮件，纯文本
        :param to_email:
        :param subject:
        :param content:
        :return:
        """
        try:
            # 创建邮件对象
            msg = MIMEText(content, 'plain', 'utf-8')  # 填写邮件内容
            msg['From'] = formataddr((self.sender_name, self.sender_email))  # 括号里的对应发件人邮箱昵称、发件人邮箱账号
            msg['To'] = formataddr(("ekko", to_email))  # 括号里的对应收件人邮箱昵称、收件人邮箱账号
            msg['Subject'] = subject  # 邮件的主题，也可以说是标题

            # 添加邮件正文
            #msg.attach(MIMEText(content, "plain", 'utf-8'))

            # 发送邮件
            with smtplib.SMTP(self.smtp_server, 587) as server:
                server.starttls()
                server.login(self.sender_email, self.auth_code)
                server.sendmail(self.sender_email, to_email, msg.as_string())

            return True
        except Exception as e:
            if '-1' in str(e) and 'b\'\\x00\\x00\\x00\'' in str(e):
                print("忽略SMTP连接关闭异常，邮件已成功发送")
                return True
            else:
                print(f"邮件发送失败: {str(e)}")
                return False

    def send_email(self, to_email, subject, content, content_type='plain', attachments=None):
        """
        发送邮件

        :param to_email: 收件人邮箱(多个邮箱用列表)
        :param subject: 邮件主题
        :param content: 邮件内容
        :param content_type: 内容类型 'plain' 或 'html'
        :param attachments: 附件列表(文件路径)
        :return: True发送成功，False发送失败
        """
        try:
            # 创建邮件对象
            msg = MIMEMultipart()
            #msg['From'] = f"{self.sender_name} <{self.sender_email}>"
            # 括号里的对应发件人邮箱昵称、发件人邮箱账号
            #msg['To'] = ', '.join(to_email) if isinstance(to_email, list) else to_email
            msg['From'] = formataddr(self.sender_name, self.sender_email)
            msg['To'] = formataddr("test", to_email)
            # 括号里的对应收件人邮箱昵称、收件人邮箱账号
            msg['Subject'] = Header(subject, 'utf-8')

            # 添加邮件正文
            msg.attach(MIMEText(content, content_type, 'utf-8'))

            # 添加附件
            if attachments:
                for file_path in attachments:
                    with open(file_path, 'rb') as f:
                        part = MIMEApplication(f.read())
                        part.add_header('Content-Disposition', 'attachment', filename=Header(
                            file_path.split('/')[-1], 'utf-8').encode())
                        msg.attach(part)

            # 发送邮件
            with smtplib.SMTP(self.smtp_server, 587) as server:
                server.starttls()
                server.login(self.sender_email, self.auth_code)
                server.sendmail(self.sender_email, to_email, msg.as_string())

            return True
        except Exception as e:
            if '-1' in str(e) and 'b\'\\x00\\x00\\x00\'' in str(e):
                print("忽略SMTP连接关闭异常，邮件已成功发送")
                return True
            else:
                print(f"邮件发送失败: {str(e)}")
                return False

    def send_email_with_images(self, to_email, subject, content, image_paths):
        """
        发送带有内嵌多张图片的邮件

        :param to_email: 收件人邮箱
        :param subject: 邮件主题
        :param content: HTML内容（需使用 <img src="cid:image1">、<img src="cid:image2"> 等引用图片）
        :param image_paths: 图片文件路径列表，按顺序对应 CID: image1, image2, ...
        :return: True 发送成功，False 发送失败
        """
        try:
            msg = MIMEMultipart()
            msg['From'] = formataddr((self.sender_name, self.sender_email))
            msg['To'] = formataddr(("收件人", to_email))
            msg['Subject'] = Header(subject, 'utf-8')

            # 添加HTML正文
            msg.attach(MIMEText(content, 'html', 'utf-8'))

            # 添加每张图片并设置唯一CID
            for idx, image_path in enumerate(image_paths, 1):
                with open(image_path, 'rb') as f:
                    img = MIMEApplication(f.read(), _subtype='png')
                    cid = f'image{idx}'
                    img.add_header('Content-ID', f'<{cid}>')
                    img.add_header('Content-Disposition', 'inline',
                                   filename=Header(image_path.split('/')[-1], 'utf-8').encode())
                    msg.attach(img)

            # 发送邮件
            with smtplib.SMTP(self.smtp_server, 587) as server:
                server.starttls()
                server.login(self.sender_email, self.auth_code)
                server.sendmail(self.sender_email, to_email, msg.as_string())

            return True
        except Exception as e:
            if '-1' in str(e) and "b'\\x00\\x00\\x00'" in str(e):
                print("忽略SMTP连接关闭异常，邮件已成功发送")
                return True
            else:
                print(f"邮件发送失败: {str(e)}")
                return False

    def send_images_via_email(self, to_email, subject, folder_name):
        """
        发送包含多张图片的邮件

        :param self: QQMailSender 实例
        :param to_email: 收件人邮箱
        :param subject: 邮件主题
        :param folder_name: 图片所在文件夹名称
        :return: True 发送成功，False 发送失败
        """
        image_paths = find_image_files(folder_name)

        if not image_paths:
            print(f"未找到任何图片文件，文件夹：{folder_name}")
            return False

        # 动态生成HTML内容
        html_content = "<h1>具体战斗情况如下列图片所示，请查阅</h1>"
        # for i in range(len(sorted_image_paths)):
        #     html_content += f"<p>图片{i + 1}：</p><img src='cid:image{i + 1}'  style='max-width: 100%;'>"
        # 每行显示2张图片，各占50%宽度
        for i in range(0, len(image_paths), 2):
            html_content += "<div style='display: flex; justify-content: space-between;'>"
            # 第一张图片
            html_content += f"<div style='width: 49%;'><p>战斗场景图片{i + 1}：</p><img src='cid:image{i + 1}' style='width: 100%; max-width: 100%;'></div>"
            # 第二张图片
            if i + 1 < len(image_paths):
                html_content += f"<div style='width: 49%;'><p>比武结束图片{i + 2}：</p><img src='cid:image{i + 2}' style='width: 100%; max-width: 100%;'></div>"
            html_content += "</div>"
        # 发送邮件
        return self.send_email_with_images(
            to_email=to_email,
            subject=subject,
            content=html_content,
            image_paths=image_paths
        )


# 使用示例
if __name__ == "__main__":
    # 初始化发送器 (需替换为实际QQ邮箱和授权码)
    # mailer = QQMailSender(
    #     # 发件人
    #     sender_name="艾克",
    #     sender_email="2287474280@qq.com",
    #     auth_code="vkdrkvkeudmcecdb"  # 在QQ邮箱设置中获取的SMTP授权码
    # )
    #
    # # 发送文本邮件
    # mailer.send_email_text(
    #     # 收件人
    #     to_email="1552281464@qq.com",  # 可以多个收件人
    #     #to_email=email_map["xqApp A7154"],
    #     subject="匹配完成",
    #     content="xqApp A7154 已完成匹配"
    # )

    # 发送HTML邮件
    # mailer.send_email(
    #     to_email="recipient@example.com",
    #     subject="HTML测试邮件",
    #     content="<h1>HTML内容</h1><p style='color:red'>红色文字</p>",
    #     content_type='html'
    # )

    # 发送带附件的邮件
    # mailer.send_email(
    #     to_email="recipient@example.com",
    #     subject="带附件邮件",
    #     content="请查收附件",
    #     attachments=["./test.txt"]  # 附件路径列表
    # )

    # 初始化发送器 (需替换为实际QQ邮箱和授权码)
    mailer = QQMailSender(
        # 发件人
        sender_name="艾克",
        sender_email="2287474280@qq.com",
        auth_code="vkdrkvkeudmcecdb"  # 在QQ邮箱设置中获取的SMTP授权码
    )
    # 发送文本邮件
    # mailer.send_email_text(
    #     # 收件人
    #     to_email=email_map["xqApp 1017"],
    #     subject="匹配完成",
    #     content="测试测试"
    # )

    mailer.send_images_via_email(
        to_email="1552281464@qq.com",
        subject="多图测试邮件",
        folder_name="hujun0"
    )